package com.generic;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.Map;

import static java.lang.annotation.ElementType.*;

/**
 * @Auther: ChenJinEn
 * @Date: 2020/8/4 22:16
 * @Description: //TODO
 */
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
@interface cje{
    String[] value() default {"aa","bb"};
    Class<?> clazz();
    int maxsize() default 0;
}

@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
@cje(clazz = String.class)
@interface bb{
    String value() default "bb";
}
@cje(clazz = SQLException.class)
@bb
public class Test {

    @Deprecated
    @cje(value = "我是一个查询语句注解",clazz = SqlSessionFactoryBuilder.class,maxsize = 100)
    public Map<String, Object> aa(Map<String, Object> a,String b){
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        //获取方法名,方法参数,方法参数泛型,方法返回值,返回值内的泛型
        Class<Test> clazz = Test.class;
        cje annotation1 = clazz.getAnnotation(cje.class);
        for (String s : annotation1.value()) {
            System.out.println(s);
        }
        System.out.println(annotation1.clazz());
        System.out.println(annotation1.maxsize());
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            method.setAccessible(true);
            //方法名
            System.out.println(method.getName());
            //带泛型的参数集合
            Type[] parameterTypes = method.getGenericParameterTypes();
            for (Type parameterType : parameterTypes) {
                if (parameterType instanceof ParameterizedType) {
                    //强转一下,取出真正的泛型类型的全限类名
                    Type[] actualTypeArguments = ((ParameterizedType) parameterType).getActualTypeArguments();
                    for (Type actualTypeArgument : actualTypeArguments) {
                        System.out.println(actualTypeArgument);
                    }
                }
            }

            //获取所有的注解
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                //方法上的所有注解
                System.out.println(annotation);
                cje c = clazz.getMethod("aa", Map.class, String.class).getAnnotation(cje.class);
                System.out.println(c.clazz());
                System.out.println(c.maxsize());
                System.out.println(c.value());
            }

            //获取带泛型参数的返回值
            Type genericReturnType = method.getGenericReturnType();
            if (genericReturnType instanceof ParameterizedType) {
                Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }


        }
    }
}
